// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package elastic

import (
	"encoding/json"
	"gitee.com/go-wares/log/base"
	"gitee.com/go-wares/log/conf"
)

// Formatter
// is a component that convert log item to string.
type Formatter struct{}

// Format
// log item as string.
func (o *Formatter) Format(item *base.Item) []byte {
	c := conf.Get()

	// Normal fields.
	entity := &Entity{
		Pid:            c.Pid,
		ServiceAddr:    c.ServiceAddr,
		ServiceName:    c.ServiceName,
		ServiceVersion: c.ServiceVersion,

		// Fil normal fields.
		Level:     item.Level,
		Message:   item.Text,
		Time:      item.Time.Format(c.TimeFormat),
		TimeMicro: item.Time.UnixMicro(),
	}

	// Fill bound fields.
	if item.Field != nil && len(item.Field) > 0 {
		entity.Fields = item.Field
	}

	// Fill stack info.
	if item.Level.IsFatal() && item.Stack != nil {
		entity.Stack = item.Stack.String()
	}

	// Append
	// opentracing fields.
	if item.TraceId != nil {
		entity.TraceId = item.TraceId.String()

		// parent span id and position.
		if item.ParentSpanId != nil {
			entity.ParentSpanId = item.ParentSpanId.String()
			entity.ParentSpanPosition = item.ParentSpanPosition
		}

		// current span id and position.
		if item.SpanId != nil {
			entity.SpanId = item.SpanId.String()
			entity.SpanPosition = item.SpanPosition
		}
	}

	if body, err := json.Marshal(entity); err == nil {
		return body
	}
	return nil
}
